package ui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.WindowConstants;

import algorithem.SuDoKu;

/**
 * The main UI panel.
 * 
 * @author ido
 * 
 */
public class BoardPanel extends javax.swing.JPanel {

	private SuDoKu gb;

	private JPanel ansPanel;
	private static JFrame frame;
	private BoardTable table;
	private String[] columnNames = { "", "", "", "", "", "", "", "", "" };

	// some example so it will be nice to start the app.
	private Object[][] cellData = { { 2, 0, 0, 9, 0, 6, 0, 0, 4 },
			{ 0, 0, 5, 0, 7, 0, 9, 0, 0 }, { 0, 3, 0, 0, 0, 0, 0, 8, 0 },
			{ 0, 0, 3, 4, 0, 7, 8, 0, 0 }, { 8, 9, 0, 2, 0, 5, 0, 6, 3 },
			{ 0, 0, 7, 6, 0, 8, 2, 0, 0 }, { 0, 7, 0, 0, 0, 0, 0, 2, 0 },
			{ 0, 0, 8, 0, 6, 0, 1, 0, 0 }, { 3, 0, 0, 7, 0, 1, 0, 0, 8 }
			
	/* another option...
	 * {0,0,0, 0,0,0, 0,0,0}, {0,0,0, 0,0,0, 0,0,0}, {0,0,0, 0,0,0, 0,0,0},
	 * 
	 * {0,0,0, 0,0,0, 0,0,0}, {0,0,0, 0,0,0, 0,0,0}, {0,0,0, 0,0,0, 0,0,0},
	 * 
	 * {0,0,0, 0,0,0, 0,0,0}, {0,0,0, 0,0,0, 0,0,0}, {0,0,0, 0,0,0, 0,0,0}
	 */
	};
	private JButton goButton;
	private JButton clearButton;
	private JButton showAllButton;

	public static void centre(Window w) {
		Dimension us = w.getSize(), them = Toolkit.getDefaultToolkit()
				.getScreenSize();
		int newX = (them.width - us.width) / 2;
		int newY = (them.height - us.height) / 2;
		w.setLocation(newX, newY);
	}

	/**
	 * The main app is here
	 * @param args
	 */
	public static void main(String[] args) {
		frame = new JFrame();
		// If we wish a nicer look & feel 
		//try {
		// UIManager.setLookAndFeel(new Plastic3DLookAndFeel());
		// }
		// catch (Exception e) {
		// e.printStackTrace();
		// }

		frame.getContentPane().setLayout(new BorderLayout(22, 22));
		frame.getContentPane().add(new BoardPanel());
		frame.setTitle("Aba Pini SuDoKu solver");
		frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
		((JPanel) frame.getContentPane()).setBorder(BorderFactory
				.createEmptyBorder(12, 12, 12, 12));
		frame.pack();
		centre(frame);
		frame.setVisible(true);
	}

	public BoardPanel() {
		super();
		initGUI();
	}

	private void initGUI() {
		try {
			table = new BoardTable(cellData, columnNames);
			table.setEditorsRederders();
			setLayout(new BorderLayout(12, 12));
			JPanel questionPanel = new JPanel();
			questionPanel.add(table);
			questionPanel.setBorder(BorderFactory
					.createTitledBorder(" The Riddle "));
			add(questionPanel, BorderLayout.NORTH);

			ansPanel = new JPanel();
			add(ansPanel, BorderLayout.CENTER);

			JPanel buttonPanel = new JPanel();
			goButton = new JButton("Solve");
			goButton.setToolTipText("Solve this sudoko");
			goButton.setMnemonic('S');
			goButton.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					solve();
					showAllButton.setEnabled(true);
				}

			});
			buttonPanel.add(goButton);

			clearButton = new JButton("Clear");
			clearButton.setToolTipText("Clear the board and type a new sudoko");
			clearButton.setMnemonic('C');
			clearButton.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					for (int i = 0; i < 9; i++) {
						for (int j = 0; j < 9; j++) {
							cellData[i][j] = 0;
						}
					}
					showAllButton.setEnabled(false);
					table.repaint();
					ansPanel.removeAll();
					frame.repaint();
				}

			});

			showAllButton = new JButton("Show The Answer");
			showAllButton.setMnemonic('A');
			showAllButton.setToolTipText("Show the full answer to this game");
			showAllButton.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					BoardTable solutionTable = new BoardTable(gb
							.getResultGrid(), columnNames);
					solutionTable.setCellSelectionEnabled(true);
					solutionTable.setDefaultRenderer(Object.class,
							new BoardTableRenderer());
					ansPanel.add(solutionTable, BorderLayout.CENTER);
					ansPanel.setBorder(BorderFactory
							.createTitledBorder(" The Answer "));
					showAllButton.setEnabled(false);
					frame.pack();
				}
			});
			showAllButton.setEnabled(false);
			buttonPanel.add(showAllButton);
			buttonPanel.add(clearButton);
			add(buttonPanel, BorderLayout.SOUTH);

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * do the magic and solve this riddle
	 */
	private void solve() {
		int[] values = new int[81];
		int k = 0;
		for (int i = 0; i < 9; i++) {
			for (int j = 0; j < 9; j++) {
				values[k++] = Integer.parseInt(cellData[i][j].toString());
			}
		}
		try {
			gb = new SuDoKu(values);
			if (gb.solve()) {
				showAllButton.setEnabled(true);
				System.out.println("done!");
				BoardTable solutionTable = new BoardTable(gb.getResultGrid(),
						columnNames);
				solutionTable.setCellSelectionEnabled(true);
				solutionTable.setDefaultRenderer(Object.class,
						new AnswerTableRenderer());
				ansPanel.removeAll();
				ansPanel.add(solutionTable, BorderLayout.CENTER);
				ansPanel.setBorder(BorderFactory
						.createTitledBorder(" The Answer "));
				frame.pack();
			} else {
				showAllButton.setEnabled(false);
				System.out.println("Could not solve!");
				JOptionPane
						.showMessageDialog(
								null,
								"Sorry... I can't solve it :) May be, the numbers are not as they should be...",
								"Opss...", JOptionPane.ERROR_MESSAGE);

			}

		} catch (Exception e) {
			showAllButton.setEnabled(false);
			JOptionPane.showMessageDialog(null, "Sorry... " + e.getMessage(),
					"Opss...", JOptionPane.ERROR_MESSAGE);
		}
	}
}
